using System;
using System.Text;

namespace PropertyExpression.ControllableQuery.Test.Queries.StringBuilding
{
    public class ModelPublicationQuery3 : IQuery<IModelPublicationInfo>
    {
        private readonly IParam<string> modelCode;
        private readonly IParam<string> modelSequence;
        private readonly ModelPublicationSearchMode modelPublicationSearchMode;

        public ModelPublicationQuery3(
            IParam<string> modelCode,
            IParam<string> modelSequence,
            ModelPublicationSearchMode modelPublicationSearchMode)
        {
            this.modelCode = modelCode;
            this.modelSequence = modelSequence;
            this.modelPublicationSearchMode = modelPublicationSearchMode;
        }

        public string TransformText()
        {
            var builder = new Q(
@"SELECT
    ModelPublication.PublicationId,
    ModelPublication.ModelCode,
    ModelPublication.ModelSequence
FROM
    ModelPublication
WHERE
    ModelPublication.ModelCode = ")._(modelCode)._(@"
    AND ModelPublication.ModelSequence = ")._(modelSequence);
            switch (modelPublicationSearchMode)
            {
                case ModelPublicationSearchMode.WithModel:
            builder._(@"
    AND EXISTS ( SELECT
                    1
                 FROM
                    Model
                 WHERE
                    Model.ModelCode = ModelPublication.ModelCode
                    AND Model.ModelSequence = ModelPublication.ModelCode )");
                    break;
                case ModelPublicationSearchMode.WithoutModel:
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
            return builder.ToString();
        }
    }

    public class ModelPublicationQuery4 : IQuery<IModelPublicationInfo>
    {
        private readonly IParam<string> modelCode;
        private readonly IParam<string> modelSequence;
        private readonly Func<ModelPublicationSearchMode> modelPublicationSearchMode;

        public ModelPublicationQuery4(
            IParam<string> modelCode,
            IParam<string> modelSequence,
            Func<ModelPublicationSearchMode> modelPublicationSearchMode)
        {
            this.modelCode = modelCode;
            this.modelSequence = modelSequence;
            this.modelPublicationSearchMode = modelPublicationSearchMode;
        }

        public string TransformText()
        {
            var q = new Q(
@"SELECT
    ModelPublication.PublicationId,
    ModelPublication.ModelCode,
    ModelPublication.ModelSequence
FROM
    ModelPublication
WHERE
    ModelPublication.ModelCode = ")._(modelCode)._(@"
    AND ModelPublication.ModelSequence = ")._(modelSequence);
            switch (modelPublicationSearchMode())
            {
                case ModelPublicationSearchMode.WithModel:
                    q._(@"
    AND EXISTS ( SELECT
                    1
                 FROM
                    Model
                 WHERE
                    Model.ModelCode = ModelPublication.ModelCode
                    AND Model.ModelSequence = ModelPublication.ModelCode )");
                    break;
                case ModelPublicationSearchMode.WithoutModel:
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
            return q.ToString();
        }
    }

    public enum ModelPublicationSearchMode
    {
        WithModel,
        WithoutModel
    }
}